//////////////////////////////////////////////////////////////////////////
#pragma once


namespace Math
{
	//////////////////////////////////////////////////////////////////////////
	inline Point3f::Point3f()
	{
	}


	inline Point3f::Point3f( const Point3f& rhs )
	:	mX( rhs.mX )
	,	mY( rhs.mY )
	,	mZ( rhs.mZ )
	{
	}


	inline Point3f::Point3f( float x, float y, float z )
	:	mX( x )
	,	mY( y )
	,	mZ( z )
	{
	}


	//////////////////////////////////////////////////////////////////////////
	inline float Point3f::X() const
	{
		return mX;
	}


	inline float Point3f::Y() const
	{
		return mY;
	}


	inline float Point3f::Z() const
	{
		return mZ;
	}


	inline void Point3f::X( float x )
	{
		mX = x;
	}


	inline void Point3f::Y( float y )
	{
		mY = y;
	}


	inline void Point3f::Z( float z )
	{
		mZ = z;
	}


	//////////////////////////////////////////////////////////////////////////
	inline float Point3f::operator ()( size_t idx ) const
	{
		assert( idx <= 3 );
		return (&mX)[ idx ];
	}


	inline void Point3f::operator ()( size_t idx, float v )
	{
		assert( idx <= 3 );
		(&mX)[ idx ] = v;
	}


	//////////////////////////////////////////////////////////////////////////
	inline void Point3f::Set( float x, float y, float z )
	{
		mX	=	x;
		mY	=	y;
		mZ	=	z;
	}


	inline const Point3f& Point3f::operator =( const Point3f& rhs )
	{
		mX	=	rhs.mX;
		mY	=	rhs.mY;
		mZ	=	rhs.mZ;
		return *this;
	}


	//////////////////////////////////////////////////////////////////////////
	inline Point3f Point3f::operator -() const							{return Point3f( -mX, -mY, -mZ );}
	inline Vector3f Point3f::operator -( const Point3f& rhs ) const		{return Vector3f( mX-rhs.mX, mY-rhs.mY, mZ-rhs.mZ );}
	inline Point3f Point3f::operator +( const Point3f& rhs ) const		{return Point3f( mX+rhs.mX, mY+rhs.mY, mZ+rhs.mZ );}
	inline void Point3f::operator -=( const Point3f& rhs )
	{
		mX	-=	rhs.mX;
		mY	-=	rhs.mY;
		mZ	-=	rhs.mZ;
	}
	inline void Point3f::operator +=( const Point3f& rhs )
	{
		mX	+=	rhs.mX;
		mY	+=	rhs.mY;
		mZ	+=	rhs.mZ;
	}


	//////////////////////////////////////////////////////////////////////////
	inline bool Point3f::IsValid() const
	{
		return (mX*0.0f)==0.0f	&&	(mY*0.0f)==0.0f	&&	(mZ*0.0f)==0.0f;
	}


	//////////////////////////////////////////////////////////////////////////
	inline const Point3f Point3f::Zero()										{return Point3f( 0, 0, 0 );}
	inline const Point3f Point3f::XAxis()										{return Point3f( 1, 0, 0 );}
	inline const Point3f Point3f::YAxis()										{return Point3f( 0, 1, 0 );}
	inline const Point3f Point3f::ZAxis()										{return Point3f( 0, 0, 1 );}


	//////////////////////////////////////////////////////////////////////////
	inline Point3f					Multiply( const Point3f& lhs, const Point3f& rhs )
	{
		return Point3f(
			lhs.X() * rhs.X(),
			lhs.Y() * rhs.Y(),
			lhs.Z() * rhs.Z()	);
	}
}
